using System;
using System.Threading;
using System.Threading.Tasks;

namespace RTMP.SimpleClient.Tests.MockServer
{
    /// <summary>
    /// Mock RTMP 服务器状态枚举
    /// </summary>
    public enum MockServerState
    {
        /// <summary>
        /// 服务器停止状态
        /// </summary>
        Stopped,

        /// <summary>
        /// 服务器启动中
        /// </summary>
        Starting,

        /// <summary>
        /// 服务器监听状态
        /// </summary>
        Listening,

        /// <summary>
        /// 客户端已连接（TCP连接建立）
        /// </summary>
        ClientConnected,

        /// <summary>
        /// 握手进行中
        /// </summary>
        HandshakeInProgress,

        /// <summary>
        /// RTMP连接已建立
        /// </summary>
        Connected,

        /// <summary>
        /// 流式传输中
        /// </summary>
        Streaming,

        /// <summary>
        /// 正在断开连接
        /// </summary>
        Disconnecting,

        /// <summary>
        /// 错误状态
        /// </summary>
        Error
    }

    /// <summary>
    /// Mock RTMP 服务器接口
    /// </summary>
    public interface IRTMPMockServer : IDisposable
    {
        /// <summary>
        /// 获取当前服务器状态
        /// </summary>
        MockServerState CurrentState { get; }

        /// <summary>
        /// 获取服务器监听端口
        /// </summary>
        int Port { get; }

        /// <summary>
        /// 获取服务器监听地址
        /// </summary>
        string Host { get; }

        /// <summary>
        /// 启动Mock服务器
        /// </summary>
        /// <param name="host">监听地址，默认为localhost</param>
        /// <param name="port">监听端口，0表示自动选择</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>启动任务</returns>
        Task StartAsync(string host = "localhost", int port = 0, CancellationToken cancellationToken = default);

        /// <summary>
        /// 停止Mock服务器
        /// </summary>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>停止任务</returns>
        Task StopAsync(CancellationToken cancellationToken = default);

        /// <summary>
        /// 等待客户端连接
        /// </summary>
        /// <param name="timeout">超时时间</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>等待任务</returns>
        Task WaitForClientConnectionAsync(TimeSpan timeout = default, CancellationToken cancellationToken = default);

        /// <summary>
        /// 等待达到指定状态
        /// </summary>
        /// <param name="expectedState">期望状态</param>
        /// <param name="timeout">超时时间</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>等待任务</returns>
        Task WaitForStateAsync(MockServerState expectedState, TimeSpan timeout = default, CancellationToken cancellationToken = default);

        /// <summary>
        /// 状态变化事件
        /// </summary>
        event EventHandler<StateChangedEventArgs>? StateChanged;

        /// <summary>
        /// 客户端连接事件
        /// </summary>
        event EventHandler<ClientConnectedEventArgs>? ClientConnected;

        /// <summary>
        /// 客户端断开事件
        /// </summary>
        event EventHandler<ClientDisconnectedEventArgs>? ClientDisconnected;

        /// <summary>
        /// 命令接收事件
        /// </summary>
        event EventHandler<CommandReceivedEventArgs>? CommandReceived;
    }

    /// <summary>
    /// 状态变化事件参数
    /// </summary>
    public class StateChangedEventArgs : EventArgs
    {
        public MockServerState PreviousState { get; }
        public MockServerState NewState { get; }
        public DateTime Timestamp { get; }

        public StateChangedEventArgs(MockServerState previousState, MockServerState newState)
        {
            PreviousState = previousState;
            NewState = newState;
            Timestamp = DateTime.UtcNow;
        }
    }

    /// <summary>
    /// 客户端连接事件参数
    /// </summary>
    public class ClientConnectedEventArgs : EventArgs
    {
        public string ClientEndpoint { get; }
        public DateTime Timestamp { get; }

        public ClientConnectedEventArgs(string clientEndpoint)
        {
            ClientEndpoint = clientEndpoint;
            Timestamp = DateTime.UtcNow;
        }
    }

    /// <summary>
    /// 客户端断开事件参数
    /// </summary>
    public class ClientDisconnectedEventArgs : EventArgs
    {
        public string ClientEndpoint { get; }
        public string? Reason { get; }
        public DateTime Timestamp { get; }

        public ClientDisconnectedEventArgs(string clientEndpoint, string? reason = null)
        {
            ClientEndpoint = clientEndpoint;
            Reason = reason;
            Timestamp = DateTime.UtcNow;
        }
    }

    /// <summary>
    /// 命令接收事件参数
    /// </summary>
    public class CommandReceivedEventArgs : EventArgs
    {
        public string CommandName { get; }
        public double TransactionId { get; }
        public object? CommandObject { get; }
        public byte[] RawData { get; }
        public DateTime Timestamp { get; }

        public CommandReceivedEventArgs(string commandName, double transactionId, object? commandObject, byte[] rawData)
        {
            CommandName = commandName;
            TransactionId = transactionId;
            CommandObject = commandObject;
            RawData = rawData;
            Timestamp = DateTime.UtcNow;
        }
    }
}